\chapter{Введение в программирование на C}
\section{Теоретические сведения}
В ходе выполнения лабораторной работы будет предложено на базе общих знаний из курса информатики и начальных теоретических знаний по программированию на C разработать программу с использованием средств, представленных ниже. 

Eclipse -- свободная интегрированная среда разработки модульных кроссплатформенных приложений. Развивается и поддерживается Eclipse Foundation.
Наиболее известные приложения на основе Eclipse Platform — различные <<Eclipse IDE>> для разработки ПО на множестве языков, в частности, C и C++.

GNU Compiler Collection (обычно используется сокращение GCC) -- набор компиляторов для различных языков программирования, разработанный в рамках проекта GNU. 
GCC является свободным программным обеспечением, распространяется фондом свободного программного обеспечения (FSF) на условиях GNU GPL и GNU LGPL и является ключевым компонентом GNU toolchain. Он используется как стандартный компилятор для свободных UNIX-подобных операционных систем.

MinGW (англ. Minimalist GNU for Windows), ранее mingw32, — компилятор, нативный программный порт GNU Compiler Collection (GCC) под Microsoft Windows, вместе с набором свободно распространяемых библиотек импорта и заголовочных файлов для Windows API. MinGW позволяет разработчикам создавать нативные приложения Microsoft Windows

Общие правила, используемые при разработке C-программ:
\begin{itemize}
\itemв начале программы перечисляются директивы препроцессора;
\itemпрограмма состоит из совокупности функций, одна из которых должна называться main();
\itemописание функции состоит из заголовка и тела функции и называется определением функции или ее реализацией;
\itemзаголовок функции содержит тип возвращаемого функцией значения, имя функции и список параметров;
\itemимя функции узнается по круглым скобкам, которые идут за именем и могут быть пустыми;
\itemтело функции заключено в фигурные скобки и состоит из ряда инструкций.
\end{itemize}

Итак, имеем простую программу, написанную с учетом соблюдения требований стандарта ISO/ANSI C.

\begin{lstlisting}
//Директивы препроцессора
#include …

int main(void)
{
  //объявления переменных;
  //инициализация переменных;
  //вызовы функции;
  return 0;
}
\end{lstlisting}

Вслед за открывающей фигурной скобкой идут объявления переменных. Все переменные, используемые в программе, должны быть объявлены, т. е. для них должны быть указаны имена и типы значений, например:
\begin{lstlisting}
int a;
float b, c;
\end{lstlisting}

В качестве выражений в языке C рассматривается совокупность элементов данных (переменных, констант и вызовов функций), объединенных знаками операций и скобками. Каждое выражение должно иметь свое значение. Результат вычисления выражения зависит от расположения знаков операций и круглых скобок в выражении, а также от приоритета выполнения операций.  

Элементы данных, используемые в выражении, называются операндами. Каждый операнд имеет тип. При вычислении выражений тип каждого операнда может быть преобразован к другому типу. Преобразования типов бывают неявными (при вычислении выражений и вызовах функций) или явными (при выполнении операций преобразования типов).    
Неявное преобразование из типа int в тип float:

\begin{lstlisting}
int a=5; float b=a;
\end{lstlisting}

К арифметическим операциям относятся операции сложения (+), вычитания (–), умножения (*), деления (/) и деления по модулю (\%) – вычисление остатка от деления. В языке отсутствует операция возведения в степень.

В одном и том же выражении могут встретиться переменные и константы разных типов, в этом случае они преобразуются к старшему типу в соответствии с приоритетами типов, установленными в языке C: long double – double – float – unsigned long – long – unsigned int – int – unsigned char – char.

В этом перечислении наивысший приоритет имеет типlong double. Компилятор преобразует “меньший” тип в “больший”. Например, если в выражении операнды имеют типыlong double,double,float и т. д., то все они на время вычислений автоматически преобразуются к старшему типу. В данном случае это будет типlong double. Тип результата будет соответствовать старшему типу в выражении.

C-программа состоит из функций, которые являются строительными элементами языка.

Каждая функция имеет заголовок и тело. Заголовок включает в себя имя функции, список аргументов, заключенный в круглые скобки, и тип возвращаемого функцией значения.  За строкой, содержащей имя функции, идет тело функции, заключенное в фигурные скобки.

В общем виде синтаксис определения функции выглядит следующим образом:

\begin{lstlisting}
return_type function_name(param_type1 param1 [, param_typeN paramN])
{
  // body
}
\end{lstlisting}

Тело функции содержит последовательность операторов языка, выполняющих некоторые действия.

return\_type определяет тип значения (результата), возвращаемого функцией. Функция может возвращать значение любого типа, за исключением массивов. 

function\_name представляет собой идентификатор, после имени функции обязательно следуют круглые скобки. В скобках указывается список формальных параметров. Каждый элемент списка формальныхпараметров состоит из имени переменной и ее типа. Все параметры функции должны объявляться отдельно, причем для каждого из них надо указывать и тип, и имя. При вызове функции формальные параметры заменяются значениями фактических аргументов.

Список параметров может быть и пустым. Такой пустой список можно указать в явном виде, поместив внутри скобок ключевое слово void, или оставить скобки пустыми.

В языке C можно выделить следующие группы операторов:
\begin{itemize}
\itemусловные;
\itemцикла;
\itemбезусловного перехода;
\itemоператоры-выражения;
\itemблоки (составные операторы).
\end{itemize}

К условным относятся операторы if и switch, к операторам цикла – for, while и do-while, к операторам безусловного перехода - break, continue, goto и return.

Операторы-выражения – это операторы, состоящие из операндов (переменных, констант, функций), знаков операций и круглых скобок, обозначающих порядок действий над операндами.

В общем виде синтаксис оператора if следующий:
\begin{lstlisting}
if (LE) OP1;
else OP2.
\end{lstlisting}
При истинном значении ЛВ выполняется оператор ОР1, в противном случае – ОР2, иногда используется и иная форма условного оператора

Оператор выбора switch (или переключатель) предназначен для выбора ветви вычислительного процесса исходя из значения управляющего выражения. Использование данного оператора целесообразно при сложном условном ветвлении.

Структура оператора следующая:
\begin{lstlisting}
switch (exp)
{
case const_exp1 : op
break;
case const_exp2 : op
break;
default : op
}
\end{lstlisting}

Значение выражения оператора switch должно быть целочисленным. Это означает, что в выражении можно использовать переменные только целого или символьного типа. Результат вычисления выражения по очереди сравнивается с каждым из константных выражений. Если в какой-либо строке находится совпадение, управление передается на соответствующую меткуcase, и выполняется связанная с ней группа операторов. Выполнение продолжается до конца тела оператора switch или пока не встретится оператор break, который передает управление из тела switch оператору, следующему за закрывающей данную конструкцию фигурной скобкой.

Применение оператора break в контексте блока switch является обычным. Без него после выполнения варианта case, который соответствует значению управляющего выражения, оператор switch продолжит свою работу, при этом будут выполнены все последующие варианты case и ветка default.

Оператор, связанный с default, выполняется, если выражение не совпало ни с одним из константных выражений в case. Оператор default не обязательно располагается в конце конструкции. Кроме того, он и сам не обязателен. В этом случае при отсутствии совпадений не выполняется ни один оператор. Не допускается совпадение константных выражений.

Ключевое слово while позволяет выполнять оператор или группу операторов до тех пор, пока условие не перестанет быть истинным.

Синтаксис: while(ЛВ) ОP;
где ЛВ – логическое выражение, ОP – тело цикла (простой или составной оператор).

Итак:
если ЛВ – истинно, выполняется ОР, затем снова проверяется ЛВ и так далее;
если ЛВ – ложно, ОР пропускается, и управление передается на оператор, следующий за телом цикла.

Поскольку проверка ЛВ выполняется перед телом цикла, цикл while называют циклом с предусловием.

Если ЛВ изначально ложно, тело цикла while не выполнится ни разу.

Оператор цикла for позволяет выполнять оператор или группу операторов заранее заданное количество раз.

Общая форма оператора
for (V1; ЛВ; V2) ОP;

где V1 – выражение, в котором производится присваивание переменной, называемой параметром цикла, начального значения (инициализация); ЛВ – условие, определяющее, следует ли в очередной раз выполнять оператор (тело цикла); V2 – выражение, в котором производится изменение переменной цикла (приращение); ОР – оператор или группа операторов.

Принцип работы:
\begin{itemize}
\itemвычисляется V1;
\itemвычисляется ЛВ;
\itemесли ЛВ истинно, выполняется ОР, затем вычисляется V2;
\itemпроверка ЛВ > ОP > V2 и т. д.
\end{itemize}
Когда ЛВ становится ложным, осуществляется переход к оператору, следующему за ОP. Если ОP – составной оператор, то его надо заключить в \{\}.
Если ЛВ сразу ложно, то ни ОР, ни V2 не выполняются ни разу.

В цикле do-while проверка условия проводится после выполнения тела цикла:
do ОP while(ЛВ)

Действие
\begin{itemize}
\itemвыполняется ОР;
\itemесли ЛВ истинно, повторяется выполнение ОР, в противном случае осуществляется переход к оператору, следующему за while.
\end{itemize}

Если в цикле должно выполняться несколько операторов, они заключаются в \{\}. Данный цикл носит название цикла с постусловием, т. е. при любом ЛВ тело цикла выполняется хотя бы один раз.

Оператор break применяется в двух случаях. Во-первых, в операторе switch с его помощью прерывается выполнение последовательности case. Во-вторых, оператор break используется для немедленного прекращения выполнения цикла без проверки его условия и передачи управления оператору, следующему после оператора цикла.

Можно сказать, что оператор continue немного похож на оператор break. Оператор break вызывает прерывание цикла, а continue – прерывание текущей итерации цикла и переход к следующей итерации.

Завершает выполнение функции, в которой он задан, и возвращает управление в вызывающую функцию. Управление передается в вызывающую функцию в точку, непосредственно следующую за вызовом.

Синтаксис: return (выражение);

Оператор return используется в 2-х случаях:
\begin{itemize}
\itemесли надо немедленно выйти из функции;
\itemесли функция должна возвращать значение.
\end{itemize}

Несколько переменных одного типа можно объединить под одним именем. Такая переменная будет представлять собой массив. Массив -- это тип данных, представляющий собой ограниченный набор упорядоченных элементов одного и того же типа, имеющих одно и то же имя.

Элементом массива является переменная. Количество элементов массива определено заранее при объявлении массива. Все элементы упорядочены -– каждому присвоен порядковый номер, который называется индексом. Доступ к конкретному элементу массива осуществляется с помощью индекса. В языке C все массивы располагаются в отдельной непрерывной области памяти. Первый элемент массива имеет наименьший адрес, а последний – наибольший.

Общая форма объявления одномерного массива имеет следующий вид:
\textit{<класс> тип имя [размер]}

Пример программы
\begin{lstlisting}
# include <stdio.h>
# define N 15
int main()
{
  float x[N],s;
  int i;
  for (i=0,s=0;i<N;++i)
  {
    printf("\n Input x[%d]",i);
    scanf("%f",&x[i]);
    s+=x[i];
  }
  printf("\n S=%f",s);
  return 0;
}
\end{lstlisting}

Объем памяти, необходимый для хранения массива, определяется типом элемента массива и количеством элементов, входящих в массив.

\section{Базовые действия по созданию проекта}
\begin{enumerate}
\itemЗапустить eclipse.
\itemВыбрать рабочую папку -- (например, d:$\backslash$temp$\backslash$lab1). Далее -- закрыть приветственное окно.
\itemСоздать новый проект -- File->New->C Project, далее -- Hello World ANSI C Project. Ввести имя, например, examp1. Выбрать Toolchain -- MinGW GCC. Нажать Next.
\itemЗаполнить предлагаемые поля (Author, Greeting и т. д.). Нажать Next.
\itemВыбрать вариант сборки только Debug. Нажать Finish.
\itemОткроется окно редактора с файлом examp1.c. Слева расположена вкладка Project Explorer. Раскрыть вкладку проекта examp1. В подвкладке Binaries видно, что автоматически собралось приложение examp1. Выбрать его правой кнопкой мыши, далее -- RunAs->C/C++ Local application. Во вкладке консоли появится приветствие.
\end{enumerate}

Полученный текст программы можно редактировать под свои нужды. Также возможно было выбрать не Hello World ANSI C Project, а Empty Project и добавить в него свой файл. А именно:

\begin{figure}[h]
\center{\includegraphics[width=1.\linewidth]{eclipse}}
\caption{Внешний вид окна eclipse}
\end{figure}

\begin{enumerate}
\itemВыбрать File->New->C Project. Ввести имя: examp2 (например). Выбрать Empty Project и нажать Next.
\itemОставить только Debug в следующем окне и нажать Finish.
\itemВыбрать в Project Explorer (вкладка слева) правой кнопкой мыши examp2 и нажать -- New->Source File. Далее ввести имя файла -- main.c.
\itemНовый файл откроется в окне. В нем введем следующий текст:
\begin{lstlisting}
#include <stdio.h>

int main()
{
	printf("Hello, Momentics!\n");
	return 0;
}
\end{lstlisting}
\itemЗапустить проект на сборку -- Project->Build All, либо иконка с изображением молотка.
\itemЗапустить программу можно также иконкой с изображением кнопки Play.
\end{enumerate}

\section{Базовые действия по отладке программы}
\begin{figure}[h]
\center{\includegraphics[width=1.\linewidth]{debug}}
\caption{Внешний вид Debug Perspecitve}
\end{figure}
\begin{enumerate}
\itemДля начала необходимо установить точку останова на какой-нибудь \textbf{исполняемой} инструкции: например, на строчке с выводом строки (в случае examp2 -- строка 2 файла main.c). Индикатор номера строки находится в правом нижнем углу в строке состояния.
\itemТочка останова устанавливается двойным нажатием левой кнопки мыши по серому полю слева от текста программы.
\itemДалее необходимо включить режим отладки: Project->Debug. При этом eclipse предложит переключиться в Debug Perspective, с чем следует согласиться. Справа от вкладки Debug появятся пиктограммы -- Resume, Terminate, Step Into, Step Over и т. д. 
\item Для отладки далее следует пользоваться ими аналогично отладчику Delphi. Прекращение отладки осуществляется нажатием кнопки Terminate и выходом в C/C++ Perspective (это происходит либо автоматически, либо выбором соответствующей иконки в правом верхнему углу).
\end{enumerate}

\section{Сборка программы из командной строки -- базовые действия}
MSYS -- это среда имитации командной строки UNIX в системе Windows.

\begin{enumerate}
\itemЗапустить MSYS. Появится приглашение командной строки (знак доллар).
\itemСоздать рабочую папку и исходные файлы: (текст далее вводить в командной строке, для каждой новой строки нажимать Enter)
\textit{
\\
\$cd d: \\
\$cd temp/lab1 \\
\$mkdir examp3 \\
\$cd examp3
}

В первой строке осуществляется переход на диск D: командой cd -- change directory. Далее -- в созданную ранее папку temp/lab1 -- путь разделяется прямым слешем.
Далее создается директория examp3 -- mkdir examp3 (make directory), и в нее осуществляется переход -- cd examp3.

\textbf{Имена директорий даются для примера!}
\itemСоздадим файл с исходным текстом:
\textit{\\
\$echo>main.c
}

Команда echo просто транслирует передаваемые ей аргументы в консоль. В данном случае ей не передается никаких аргументов. Оператор перенаправления (>) указывает на то, что вместо консоли, результат работы программы echo перенаправляется в файл main.c. Таким образом, мы получим файл с пустым содержимым под названием main.c.
\itemОткрываем файл любым текстовым редактором: 

\textit{
\$notepad2.exe main.c
}

В данном случае запускается программа notepad2.exe с параметром main.c, который воспринимается как имя файла.
\itemОтредактируем файл так же, как в предыдущем подразделе:
\begin{lstlisting}
#include <stdio.h>

int main()
{
	printf("Hello, MSYS!\n");
	return 0;
}
\end{lstlisting}
\itemСкомпилируем программу:

\textit{
\$gcc main.c -g -o examp3
}

В результае мы получим файл examp3.exe, определяемый ключом запуска -o. Ключ -g определяет, что в результирующем файле содержится отладочная информация. Убедиться, что он действительно появился, можно, запустив:

\textit{
\$ls -l
}

В данном случае запускается программа ls (list), с ключом -l (--long). В результате можно видеть:

\textit{
-rwxr-xr-x 1 kir Администраторы 15640 Mar  3 22:51 examp3.exe
\newline
-rw-r--r-- 1 kir Администраторы    27 Mar  3 22:51 main.c
}

\itemЗапустим программу:

\textit{
\$examp3.exe
}

Результат отобразится в консоли.
\end{enumerate}
\section{Отладка программы из командной строки -- базовые действия}
\begin{enumerate}
\itemНаходясь в папке с программой examp3 (в предыдущем примере -- d:/temp/lab1/examp3) запустим gdb с параметром -- имя отлаживаемой программы:

\textit{
\$gdb examp3
}

\begin{scriptsize}
Имя текущей папке отображается над знаком доллар в командной строке. Узнать имя текущей папки также можно, набрав команду pwd.
\end{scriptsize}
\itemВ случае успешного запуска gdb с параметром examp3, бинарный файл загружается в память особым образом: так, что его выполнение теперь можно контролировать. Заметим, что приглашение командной строки поменялось со знака доллар на <<(gdb)>>. Теперь мы находимся в командной строке gdb. Код программы можно просмотреть:

\textit{
(gdb) list main
}

Данная команда отладчику показывает все строки файла, содержащего точку входа в программу (функцию main). Установим точку останова:

\textit{
(gdb) b main
}

В этом случае точка останова установится в начале функции main. Также можно установить точку останова в определенной строчке, скажем, в файле main.c:


\textit{
(gdb) b main.c:4
}

Удаляются точки останова командой delete.

\item Запустим программу:

\textit{
(gdb) run
}

Программа дойдет до точки останова с выводом ее содержимого на экран. Следующий шаг можно сделать командой next, <<войти внутрь>> функции можно при помощи команды step.

\itemВыход из gdb осуществляется при помощи директивы quit.
\end{enumerate}

\section{Сборка проекта из нескольких файлов из IDE -- базовые действия}
\begin{enumerate}
\itemСоздадим проект из нескольких файлов (возможно, на базе examp2). В Project Manager выберем examp2 правой кнопкой мыши, далее New->Header File. Вводим имя: integrator.h. Аналогично добавляем integrator.c.
\itemЗаполним файлы содержимым. В integrator.h:
\begin{lstlisting}
#ifndef INTEGRATOR_H_
#define INTEGRATOR_H_

double integrate(double a, double b);

#endif /* INTEGRATOR_H_ */
\end{lstlisting}

В integrator.c:
\begin{lstlisting}

const double level = 1.0;

double integrate(double a, double b)
{
	return level*(b - a);
}

\end{lstlisting}
\itemМодифицируем main.c:
\begin{lstlisting}
#include <stdio.h>
#include "integrator.h"

int main()
{
	printf("integrate(0, 0) = %f", integrate(0, 0));

	return 0;
}
\end{lstlisting}

\itemТеперь проект можно собрать: Project->Build All (Ctrl+B). В окне консоли можно видеть:
\textit{
\\
**** Internal Builder is used for build               ****\\
gcc -O0 -g3 -Wall -c -fmessage-length=0 -omain.o main.c\\
gcc -oexamp2.exe main.o integrator.o \\
Build complete for project examp2 \\
Time consumed: 400  ms.  \\
}
\end{enumerate}

\section{Работа с GNU Make -- приципы}
%http://citforum.ru/operating_systems/gnumake/gnumake_04.shtml
Утилита make, входящая в состав практически всех Unix-подобных операционных систем -- это традиционное средство, применяемое для сборки программных проектов. Она является универсальной программой для решения широкого круга задач, где одни файлы должны автоматически обновляться при изменении других файлов.

При запуске программа make читает файл с описанием проекта (make-файл) и, интерпретируя его содержимое, предпринимает необходимые действия. Файл с описанием проекта представляет собой текстовой файл, где описаны отношения между файлами проекта, и действия, которые необходимо выполнить для его сборки. 
Основным "строительным элементом" make-файла являются правила (rules). В общем виде правило выглядит так:

\begin{lstlisting}{language=[gnu]make}
 <target_1> <target_2> ... <target_n>: <dep_1> <dep_2> ... <dep_n>
        <command_1>
        <command_2>
        ...
        <command_n>
\end{lstlisting}

Цель (target) -- это некий желаемый результат, способ достижения которого описан в правиле. Цель может представлять собой имя файла. В этом случае правило описывает, каким образом можно получить новую версию этого файла. В следующем примере:

\begin{lstlisting}
    iEdit: main.o Editor.o TextLine.o
        gcc  main.o Editor.o TextLine.o -o iEdit
\end{lstlisting}

целью является файл iEdit (исполняемый файл программы). Правило описывает, каким образом можно получить новую версию файла iEdit (скомпоновать из перечисленных объектных файлов).

Цель также может быть именем некоторого действия. В таком случае правило описывает, каким образом совершается указанное действие. В следующем примере целью является действие clean (очистка).

\begin{lstlisting}
    clean:
        rm *.o iEdit
\end{lstlisting}

Подобного рода цели называются псевдоцели (pseudotargets) или абстрактные цели (phony targets).

Зависимость (dependency)- это некие "исходные данные", необходимые для достижения указанной в правиле цели. Можно сказать что зависимость - это "предварительное условие" для достижения цели. Зависимость может представлять собой имя файла. Этот файл должен существовать, для того чтобы можно было достичь указанной цели. В следующем правиле:

\begin{lstlisting}
    iEdit: main.o Editor.o TextLine.o
        gcc  main.o Editor.o TextLine.o -o iEdit
\end{lstlisting}

файлы main.o, Editor.o и TextLine.o являются зависимостями. Эти файлы должны существовать для того, чтобы стало возможным достижение цели - построение файла iEdit.

Зависимость также может быть именем некоторого действия. Это действие должно быть предварительно выполнено перед достижением указанной в правиле цели. В следующем примере зависимость clean\_obj является именем действия (удалить объектные файлы программы):

\begin{lstlisting}
    clean_all:  clean_obj
        rm iEdit
    clean_obj:
        rm *.o
\end{lstlisting}

Для того чтобы цель clean\_all была достигнута, нужно сначала выполнить действие (достигнуть цели) clean\_obj.

Команды - это действия, которые необходимо выполнить для обновления либо достижения цели. В следующем примере:

\begin{lstlisting}
    iEdit: main.o Editor.o TextLine.o
        gcc  main.o Editor.o TextLine.o -o iEdit
\end{lstlisting}

командой является вызов компилятора GCC. Утилита make отличает строки, содержащие команды, от прочих строк make-файла по наличию символа табуляции (символа с кодом 9) в начале строки. В приведенном выше примере строка:

\begin{lstlisting}
    gcc  main.o Editor.o TextLine.o -o iEdit
\end{lstlisting}

\textbf{должна начинаться с символа табуляции}. 

\section{Работа с GNU Make из IDE}
\begin{enumerate}
\itemСоздадим проект: File->New->C Project. Выберем (в самом низу) Makefile Project->Empty Project. Введем имя: examp4. Toolchain (меню справа) можно не выбирать (Other Toolchain). Сразу можно нажать Finish.
\itemСкопируем в проект файлы из examp2: в Project Explorer выделим их с помощью мыши, Ctrl+C, далее левой кнопкой выберем examp4, Ctrl+V.
\itemДобавим сценарий сборки: правая кнопка мыши на examp4, New->File. Имя: Makefile.
\itemЗаполним его содержимым:
\begin{lstlisting}{language=make}
CC = gcc

all: examp4

examp4: integrator.o main.o
	gcc -o examp4 $+
	
integrator.o: integrator.c integrator.h
main.o: main.c integrator.h

clean:
  rm *.o *.exe
\end{lstlisting}
В данном файле есть два неявных правила (integrator.o и main.o) и одно явное -- examp4. В начала определяется переменная CC, которая используется make'ом для подстановки компилятора C. Последнее правило используется для удаления результатов сборки. В данном случае запускается программа rm с параметром -- все файлы с расширением *.o и *.exe в текущей папке.
\itemУбедиться в работоспособности сценария сборки можно и из командной строки MSYS, зайдя в папку с проектом и набрав там make:
\textit{\\
\$cd d:\\
\$cd temp/lab1/examp4\\
\$make clean\\
\$make\\ 
}
Поскольку программа была уже собрана, пришлось удалить результаты сборки, чтобы собрать ее снова для проверки.
\end{enumerate}

\section{Индивидуальное задание}
\begin{enumerate}
\itemПроделать вышеописанные процедуры самостоятельно, ознакомившись в том числе и с принципами написания Makefile'ов.
\itemНаписать программу в соответствии с вариантом (массивы и матрицы состоят из целых чисел):
\begin{enumerate}
\itemВвести массив из 10 элементов с клавиатуры. Найти наибольший элемент (в отдельной функции). Вывести его на экран. Функцию поиска наибольшего элемента оформить в отдельном файле find\_max.c, прототип объявить в find\_max.h и включить его в main.c:
\begin{lstlisting}
#ifndef FIND_MAX_H__
#define FIND_MAX_H__

int find_max(int* array, int num);
#endif
\end{lstlisting}
\itemВвести массив из 10 элементов с клавиатуры. Найти наименьший элемент (в отдельной функции). Вывести его на экран. Функцию поиска наибольшего элемента оформить в отдельном файле find\_min.c, прототип объявить в find\_max.h и включить его в main.c.
\begin{lstlisting}
#ifndef FIND_MIN_H__
#define FIND_MIN_H__

int find_min(int* array, int num);
#endif
\end{lstlisting}
\itemВвести матрицу 3x3 с клавиатуры. Найти наибольший элемент (в отдельной функции). Вывести его на экран. Функцию поиска наибольшего элемента оформить в отдельном файле find\_min.c, прототип объявить в find\_max.h и включить его в main.c.
\begin{lstlisting}
#ifndef FIND_MAX_H__
#define FIND_MAX_H__

int find_max(int matrix[3][3])
#endif
\end{lstlisting}
\itemВвести матрицу 3x3 с клавиатуры. Найти наименьший элемент (в отдельной функции). Вывести его на экран. Функцию поиска наибольшего элемента оформить в отдельном файле find\_min.c, прототип объявить в find\_min.h и включить его в main.c.
\begin{lstlisting}
#ifndef FIND_MIN_H__
#define FIND_MIN_H__

int find_min(int matrix[3][3])
#endif
\end{lstlisting}
\end{enumerate}
\end{enumerate}

